/* -*-c++-*- OpenSceneGraph - Copyright (C) 2014 ADIT GmbH
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#ifndef OSGUTIL_HALFFLOATARRAYADAPTER
#define OSGUTIL_HALFFLOATARRAYADAPTER 1

#include <osg/Array>

namespace osgUtil {
class HalfFloatArrayAdapter : public osg::Array {
public:
    HalfFloatArrayAdapter(unsigned int elementSize = 3);

    /**
     * @brief HalfFloatArrayAdapter
     * @param elementSize number of elements in an entry (should be 2, 3 or 4)
     * @param size total number of entries
     * @param data pointer to the data
     * @param takeOwnership whether the class should free the data after use.
     *
     * Example: Wrapping a piece of memory that stores four vectors with three
     * components:
     *
     * new HalfFloatArrayAdapter(3, 4, data);
     *
     */
    HalfFloatArrayAdapter(unsigned int elementSize, unsigned int size,
                          GLvoid *data,
                          bool takeOwnership = false);

    HalfFloatArrayAdapter(const HalfFloatArrayAdapter& other,
                          const osg::CopyOp& copyop);

    virtual ~HalfFloatArrayAdapter();

    virtual Object *cloneType() const {
        return new HalfFloatArrayAdapter;
    }

    virtual osg::Object* clone(const osg::CopyOp& copyop) const {
        return new HalfFloatArrayAdapter(*this, copyop);
    }

    virtual int compare(unsigned int lhs, unsigned int rhs) const;

    virtual void accept(osg::ArrayVisitor& av) { av.apply(*this); }
    virtual void accept(osg::ConstArrayVisitor& cav) const { cav.apply(*this); }
    virtual void accept(unsigned int index, osg::ValueVisitor& vv)
    {
        vv.apply(_data[index * _elementSize]);
    }
    virtual void accept(unsigned int index, osg::ConstValueVisitor& cvv) const
    {
        cvv.apply(_data[index * _elementSize]);
    }

    virtual unsigned int getElementSize() const { return _elementSize; }
    virtual unsigned int getNumElements() const { return _size; }
    virtual const GLvoid *getDataPointer() const { return _data; }
    virtual unsigned int getTotalDataSize() const { return _elementSize * _size; }

    virtual void reserveArray(unsigned int) { OSG_NOTICE<<"reserveArray() is not supported" << std::endl; }
    virtual void resizeArray(unsigned int num) { OSG_NOTICE<<"resizeArray() is not supported" << std::endl; }
private:
    GLushort *_data;
    unsigned int _size;
    unsigned int _elementSize;
    bool _ownsData;
};
}

#endif // OSGUTIL_HALFFLOATARRAYADAPTER
